<script setup lang="ts">
import {ref} from "vue";
import type ButtonProp from "./type/ButtonProp.ts";
import type ButtonEmit from "./type/ButtonEmit.ts";
import useButton from "./composable/useButton.ts";

const $emit = defineEmits<ButtonEmit>()

const $prop = withDefaults(defineProps<ButtonProp>(), {
  type: "primary",
  ghost: false,
  text: false,
  pageSize: "medium",
  disabled: false,
  loading: false,
  circle: false,
  htmlType: "button",
})

const {
  padding,
  fontSize,
  minHeight,
  minWidth,
  textColor,
  backgroundColor,
  borderColor,
  textColorHover,
  backgroundColorHover,
  borderColorHover,
  textColorActive,
  backgroundColorActive,
  borderColorActive,
} = useButton($prop, $emit)

const focused = ref(false)
const rippleKey = ref(0) // 用于触发动画重新执行
const showRipple = ref(false)

// 上一次按钮点击时间
let lastClickTime = 0
// 处理点击事件
const handleClick = (event: MouseEvent) => {
  // 先检查按钮状态
  if ($prop.disabled || $prop.loading) {
    return
  }

  const currentClickTime = Date.now()

  // 防抖检查
  if (currentClickTime - lastClickTime < 500) {
    console.warn('点击的太频繁，至少间隔500ms')
    return
  }

  if (!$prop.disabled && !$prop.loading) {
    // 只有非 text 按钮才显示光晕效果
    if (!$prop.text) {
      showRipple.value = false
      rippleKey.value++
      setTimeout(() => {
        showRipple.value = true
      }, 10)
    }
    $emit('click', event)

    // 更新时间戳
    lastClickTime = currentClickTime
  }
}

// 添加动画结束处理函数
const onRippleEnd = () => {
  showRipple.value = false
}

</script>

<template>
  <div class="button-container">
    <button
        class="btn"
        :class="{'btn__circle': circle, 'btn__text': text, 'btn__rainbow': $prop.type === 'rainbow', 'btn__ghost': $prop.ghost, 'btn__focused': focused, disabled, loading}"
        :disabled="disabled"
        @click="handleClick"
        @focus="focused = true"
        @blur="focused = false"
        :type="htmlType"
    >

      <!-- 图标 -->
      <template v-if="$prop.icon">
        <component v-if="$prop.loading" is="loading-running" class="btn__icon"/>
        <component v-else :is="$prop.icon" class="btn__icon"/>
      </template>

      <!-- 文本内容 -->
      <span v-if="!$prop.circle && $slots.default" class="btn__content"
            :class="{'btn__content--rainbow': $prop.type === 'rainbow' && $prop.text}">
        <slot/>
      </span>
    </button>

    <!-- 光晕效果 - 只对非 text 按钮显示 -->
    <div
        v-if="showRipple && !$prop.text"
        :key="rippleKey"
        class="btn__ripple"
        @animationend="onRippleEnd"
    />

    <div v-if="disabled || loading" class="btn-mask" :class="{disabled, loading}">
      <template v-if="!$prop.icon && $prop.loading">
        <component is="loading-running" class="btn__icon"/>
      </template>
    </div>
  </div>
</template>

<style scoped>
.button-container {
  display: inline-block;
  position: relative;
  margin: 2px 2px;
}

/* 基础按钮样式 */
.btn {
  /* 动态样式 */
  padding: v-bind(padding);
  font-size: v-bind(fontSize);
  min-height: v-bind(minHeight);
  min-width: v-bind(minWidth);
  color: v-bind(textColor);
  background-color: v-bind(backgroundColor);
  /* 基础样式 */
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  border: 1px solid v-bind(borderColor);
  border-radius: 2px;
  font-family: inherit;
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  outline: none;
  transition: all 0.2s ease;
  white-space: nowrap;
  user-select: none;
  box-sizing: border-box;
}

/* 悬停状态 */
.btn:hover {
  color: v-bind(textColorHover);
  background-color: v-bind(backgroundColorHover);
  border-color: v-bind(borderColorHover);
}

/* 激活状态 */
.btn:active {
  color: v-bind(textColorActive);
  background-color: v-bind(backgroundColorActive);
  border-color: v-bind(borderColorActive);
}

/* 阴影 */
.btn:not(.btn__text) {
  box-shadow: none;
}

.btn:hover:not(.btn__text) {
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}

.btn:active:not(.btn__text) {
  box-shadow: none;
}

/* 获取焦点状态 */
.btn.btn__focused {
  color: v-bind(textColorActive);
  background-color: v-bind(backgroundColorActive);
  border-color: v-bind(borderColorActive);
}

/* 圆形按钮 */
.btn__circle {
  border-radius: 50%;
  padding: v-bind(padding);
}

.btn.disabled {
  opacity: 0.5;
  filter: grayscale(0.3);
}

.btn.loading {
  opacity: 0.7;
  filter: grayscale(0.3);
}

/* 图标样式 */
.btn__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1em;
  height: 1em;
  line-height: 1;
}

/* 内容样式 */
.btn__content {
  display: inline-flex;
  align-items: center;
}

/* 文本按钮特殊样式 */
.btn__text {
  border-width: 0;
}

.btn-mask {
  position: absolute;
  inset: 0;
  background: transparent;
  z-index: 10;

  display: flex;
  justify-content: center;
  align-items: center;
}

.btn-mask.disabled {
  cursor: not-allowed;
}

.btn-mask.loading {
  cursor: wait;
}

/* 光晕扩散效果 - 以按钮边框为基准向外扩散 */
.btn__ripple {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  border: 1px solid v-bind(borderColor);
  box-sizing: border-box;
  opacity: 0.8;
  pointer-events: none;
  animation: ripple-expand-outward 0.6s ease-out forwards;
}

/* 圆形按钮的光晕效果 */
.btn__circle + .btn__ripple {
  border-radius: 50%;
}

/* 向外扩散动画 */
@keyframes ripple-expand-outward {
  0% {
    transform: scale(1);
    opacity: 0.8;
  }
  50% {
    opacity: 0.4;
  }
  100% {
    transform: scale(1.3);
    opacity: 0;
  }
}
</style>

<style scoped v-if="$prop.type === 'rainbow'">
/* 导入七彩按钮的样式 */
@import './style/rainbow.css';
</style>